"""
@-*- coding: utf-8 -*-
@ python: 3.12.3
@ 创建者: JacksonCode
@ 创建时间: 2025-11-06
@ 描述: 认证装饰器和工具
"""
from functools import wraps
from flask import jsonify, request
from flask_jwt_extended import verify_jwt_in_request, get_jwt_identity, jwt_required
from app.services.auth import AuthService


def token_required(f):
    """JWT令牌验证装饰器"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        try:
            verify_jwt_in_request()
            return f(*args, **kwargs)
        except Exception as e:
            return jsonify({
                "code": 401,
                "message": "令牌验证失败",
                "data": None
            }), 401
    
    return decorated_function


def admin_required(f):
    """管理员权限验证装饰器"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        try:
            verify_jwt_in_request()
            current_user_id = get_jwt_identity()
            user = AuthService.get_user_by_id(current_user_id)
            
            if not user or not user.is_admin:
                return jsonify({
                    "code": 403,
                    "message": "需要管理员权限",
                    "data": None
                }), 403
                
            return f(*args, **kwargs)
        except Exception as e:
            return jsonify({
                "code": 401,
                "message": "令牌验证失败",
                "data": None
            }), 401
    
    return decorated_function


def self_or_admin_required(f):
    """用户本人或管理员权限验证装饰器"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        try:
            verify_jwt_in_request()
            current_user_id = get_jwt_identity()
            user = AuthService.get_user_by_id(current_user_id)
            
            # 检查是否是管理员或操作自己的资源
            target_user_id = kwargs.get('user_id') or request.view_args.get('user_id')
            
            if not user or (not user.is_admin and current_user_id != target_user_id):
                return jsonify({
                    "code": 403,
                    "message": "权限不足",
                    "data": None
                }), 403
                
            return f(*args, **kwargs)
        except Exception as e:
            return jsonify({
                "code": 401,
                "message": "令牌验证失败",
                "data": None
            }), 401
    
    return decorated_function


def rate_limit(max_requests=5, window=60, scope="ip"):
    """简单的请求频率限制装饰器
    
    Args:
        max_requests: 时间窗口内最大请求数
        window: 时间窗口（秒）
        scope: 限制范围（ip或user）
    """
    # 使用内存存储请求记录（生产环境应使用Redis等）
    request_records = {}
    
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            # 获取限制键
            if scope == "ip":
                limit_key = request.remote_addr
            else:  # user
                try:
                    verify_jwt_in_request()
                    limit_key = f"user_{get_jwt_identity()}"
                except:
                    limit_key = request.remote_addr
            
            # 获取当前时间
            import time
            current_time = int(time.time())
            
            # 清理过期记录
            if limit_key in request_records:
                request_records[limit_key] = [
                    req_time for req_time in request_records[limit_key]
                    if current_time - req_time < window
                ]
            else:
                request_records[limit_key] = []
            
            # 检查是否超过限制
            if len(request_records[limit_key]) >= max_requests:
                return jsonify({
                    "code": 429,
                    "message": f"请求过于频繁，请在{window}秒后重试",
                    "data": None
                }), 429
            
            # 记录当前请求
            request_records[limit_key].append(current_time)
            
            return f(*args, **kwargs)
        
        return decorated_function
    
    return decorator


def validate_json(required_fields=None, optional_fields=None):
    """JSON数据验证装饰器
    
    Args:
        required_fields: 必填字段列表
        optional_fields: 可选字段列表
    """
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            # 检查Content-Type
            if not request.is_json:
                return jsonify({
                    "code": 400,
                    "message": "请求必须是JSON格式",
                    "data": None
                }), 400
            
            # 获取JSON数据
            data = request.get_json()
            
            if data is None:
                data = {}
            
            # 验证必填字段
            if required_fields:
                from app.utils.validators import validate_required_fields
                missing_field = validate_required_fields(data, required_fields)
                if missing_field:
                    return jsonify({
                        "code": 400,
                        "message": f"缺少必填字段: {missing_field}",
                        "data": None
                    }), 400
            
            # 过滤只允许的字段
            if optional_fields is not None:
                allowed_fields = set(required_fields or []) | set(optional_fields or [])
                filtered_data = {k: v for k, v in data.items() if k in allowed_fields}
                request.json = filtered_data
            
            return f(*args, **kwargs)
        
        return decorated_function
    
    return decorator


def get_current_user():
    """获取当前登录用户"""
    try:
        verify_jwt_in_request()
        user_id = get_jwt_identity()
        return AuthService.get_user_by_id(user_id)
    except:
        return None


def is_admin(user_id=None):
    """检查用户是否是管理员
    
    Args:
        user_id: 用户ID，如果为None则检查当前用户
        
    Returns:
        如果是管理员返回True，否则返回False
    """
    try:
        if user_id is None:
            verify_jwt_in_request()
            user_id = get_jwt_identity()
        
        user = AuthService.get_user_by_id(user_id)
        return user and user.is_admin
    except:
        return False